package com.sc.nft.admin.rpc;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.admin.request.*;
import com.sc.nft.admin.vo.DaoAccountBankInfoVO;
import com.sc.nft.admin.vo.DaoWithdrawRecordVO;
import com.sc.nft.dao.*;
import com.sc.nft.dto.IdRequest;
import com.sc.nft.dto.llian.LlRandomPwdDTO;
import com.sc.nft.dto.wallet.DaoOpenWalletDTO;
import com.sc.nft.dto.wallet.VerifyOpenAccountDTO;
import com.sc.nft.dto.wallet.WalletFlowDTO;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.AccountStatusEnum;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.enums.wallet.DaoWalletTypeEnum;
import com.sc.nft.exception.GlobalException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.sc.nft.helper.LlPayHelper;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import com.tencentcloudapi.faceid.v20180301.models.PhoneVerificationRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/rpc/pay")
@Api(tags = "内部支付接口")
public class BusinessPayRpc {

    private final DaoCustomerOpenAccountService customerOpenAccountService;
    private final DaoAccountBankInfoDao daoAccountBankInfoDao;
    private final DaoWalletService daoWalletService;
    private final Redisson redisson;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final DaoTransferService daoTransferService;
    private final DaoCustomerOpenAccountDao customerOpenAccountDao;
    private final LlBankDao llBankDao;
    private final UserInfoDao userInfoDao;
    private final FilterIncomeListDao filterIncomeListDao;
    private final DaoWithdrawRecordDao daoWithdrawRecordDao;

    private final RedisTemplate redisTemplate;
    private final SmsCodeRecordService smsCodeRecordService;

    private final LlRegionDao llRegionDao;

    private final LlPayHelper llPayHelper;

    private final ExpenditureRecordService expenditureRecordService;


    final Map<String,String> txnType = new HashMap<String,String>(){{
        put("USER_TOPUP","用户充值");
        put("MCH_TOPUP","商户充值");
        put("GENERAL_CONSUME","普通消费");
        put("SECURED_CONSUME","担保消费");
        put("SECURED_CONFIRM","担保确认");
        put("INNER_FUND_EXCHANGE","内部代发");
        put("INNER_DIRECT_EXCHANGE","定向内部代发");
        put("OUTER_FUND_EXCHANGE","外部代发");
        put("ACCT_CASH_OUT","账户提现");
        put("SERVICE_FEE","手续费收取");
        put("CAPITAL_CANCEL","手续费应收应付核销");
        put("ADVANCE_PAY","垫资调账");
    }} ;

    @ApiOperation(value = "获取连连企业绑卡银行卡列表", notes = "获取连连企业绑卡银行卡列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getLlBank", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<List<LlBankVO>> getLlBank() {
        String key = RedisKeyEnum.LL_BANK.getKey();
        Boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            return Result.success(JSONObject.parseArray(Convert.toStr(redisTemplate.opsForValue().get(key)), LlBankVO.class));
        }
        List<LlBankVO> llBankVOS = BeanUtil.copyToList(llBankDao.list(), LlBankVO.class);
        redisTemplate.opsForValue().set(key, JSONObject.toJSONString(llBankVOS));
        return Result.success(llBankVOS);
    }



    @ApiOperation(value = "商户查看市值账号账单", notes = "商户查看市值账号账单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/merchantViewBill", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public PageResult<MerchantViewBillVO> merchantViewBill(@Valid @RequestBody MerchantViewBillDTO request) {
        Page<MerchantViewBillVO> page=expenditureRecordService.merchantViewBill(request.getUserId(),request.getStartTime(),request.getEndTime(),request.getPageNo(),request.getPageSize(),request.getType());
        return PageResult.success(page);
    }


    @ApiOperation(value = "dao找回密码", notes = "dao找回密码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoFindPwd", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public Result daoFindPwd(@Valid @RequestBody DaoOperatorRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        return Result.success(llPayHelper.daoFindPwd(request.getOperatorId(),userCreatorInfo.getDaoUuid()).getString("token"));
    }

    @ApiOperation(value = "dao密码验证", notes = "dao密码验证", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoVerifyPwd", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public Result daoVerifyPwd(@Valid @RequestBody DaoFindPwdRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        llPayHelper.daoPwdVerify(request.getOperatorId(),userCreatorInfo.getDaoUuid(),request.getToken(),request.getSmsCode(),request.getRandomKey(),request.getPwd());
        return Result.success();
    }

    @ApiOperation(value = "撤销申请", notes = "撤销申请", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/revoke", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public Result revoke(@Valid @RequestBody DaoRevokeRequest request) {
        daoTransferService.revoke(request.getId(),request.getDaoId(),request.getOperatorId());
        return Result.success();
    }


    @ApiOperation(value = "转账记录", notes = "转账记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoTransferPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public PageResult<DaoTransferDetailVO> daoTransferPage(@Valid @RequestBody DaoTransferPageRequest request) {
        Page<DaoTransferDetailVO> records = daoTransferService.getRecords(request.getDaoId(), null, request.getType(), null,
                null, null, request.getStatus(), request.getStartTime(), request.getEndTime(), request.toMp());
        for (DaoTransferDetailVO record : records.getRecords()) {
            record.setTypeTxt(record.getType().getDescription());
        }
        return PageResult.success(records);
    }

    @ApiOperation(value = "dao钱包明细", notes = "dao钱包明细", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/walletDetailPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiIgnore
    public PageResult<DaoWalletDetailVO> walletDetailPage(@Valid @RequestBody DaoWalletDetailPageRequest request) {
        Page<DaoWalletDetail> daoWalletDetailPage = daoWalletService.getDaoWalletDetailPage(request.getDaoId(),request.getType(), request.getStartTime(), request.getEndTime(), request.toMp());
        Page<DaoWalletDetailVO> page = new Page<>(daoWalletDetailPage.getCurrent(),daoWalletDetailPage.getSize(),daoWalletDetailPage.getTotal());
        List<DaoWalletDetailVO> result = Lists.newArrayList();
        for (DaoWalletDetail record : daoWalletDetailPage.getRecords()) {
            DaoWalletDetailVO daoWalletDetailVO = new DaoWalletDetailVO();
            daoWalletDetailVO.setAmount(record.getAmount());
            daoWalletDetailVO.setBeforeAmount(record.getBeforeAmount());
            daoWalletDetailVO.setAfterAmount(record.getAfterAmount());
            daoWalletDetailVO.setType(record.getType());
            if(daoWalletDetailVO.getType()== DaoWalletTypeEnum.MARKET_OUT||daoWalletDetailVO.getType()== DaoWalletTypeEnum.MARKET_IN){
                daoWalletDetailVO.setAccount(userInfoDao.getUserTelById(record.getSourceId()));
            }

            daoWalletDetailVO.setTypeTxt(daoWalletDetailVO.getType().getDescription());
            daoWalletDetailVO.setRemark(record.getRemark());
            daoWalletDetailVO.setIsAdd(record.getIsAdd());
            daoWalletDetailVO.setCreateTime(record.getCreateTime());
            result.add(daoWalletDetailVO);
        }
        page.setRecords(result);
        return PageResult.success(page);
    }



    @ApiOperation(value = "获取连连地域", notes = "获取连连地域", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getLlRegion", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<List<LlRegionVO>> getLlBank(@Valid @RequestBody LlRegionDTO llRegionDTO) {
        List<LlRegion> llRegion = llRegionDao.getLlRegion(llRegionDTO.getPid());
        return Result.success(BeanUtil.copyToList(llRegion, LlRegionVO.class));
    }

    @ApiOperation(value = "获取DAO密码控件", notes = "获取密码控件", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getDaoPwdElement", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<PwdElementVO> getDaoPwdElement(@Valid @RequestBody DaoPwdElementRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        return Result.success(llPayHelper.getDaoPwdElement(request.getId(),userCreatorInfo.getDaoUuid(),request.getScene(),request.getAmount()));
    }

    @ApiOperation(value = "获取随机因子", notes = "获取随机因子", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getDaoRandom", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<LlRandomPwdDTO> getDaoRandom(@Valid @RequestBody DaoOperatorRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        return Result.success(llPayHelper.getDaoRandom(request.getOperatorId(),userCreatorInfo.getDaoUuid()));
    }
    @ApiOperation(value = "提现申请", notes = "提现申请", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/applyWithdraw", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<Long> applyWithdraw(@Valid @RequestBody DaoApplyWithdrawRequest request) {
        DaoCustomerOpenAccount customerOpenAccount = customerOpenAccountDao.getById(request.getWalletId());
        if(ObjectUtil.isNull(customerOpenAccount)||customerOpenAccount.getDaoId().longValue()!=request.getDaoId().longValue()){
            return Result.fail("未找到开户记录");
        }
        if(customerOpenAccount.getStatus()!=AccountStatusEnum.SUCCESS){
            return Result.fail("开户尚未完成，无法提现");
        }
        DaoAccountBankInfo accountBankInfo = daoAccountBankInfoDao.getById(request.getWithdrawBankId());
        if(ObjectUtil.isNull(accountBankInfo)||accountBankInfo.getDaoOpenAccountId().longValue()!=request.getWalletId().longValue()){
            return Result.fail("未找到对公账户记录");
        }
        return Result.success(llPayHelper.daoWithdraw(customerOpenAccount,request.getOperatorId(),accountBankInfo,request.getAmount(),request.getPassword(),request.getRandomKey()));
    }


    @ApiOperation(value = "提现验证", notes = "提现验证", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/withdrawVerify", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result  withdrawVerify(@Valid @RequestBody DaoWithdrawVerifyRequest request) {
        DaoWithdrawRecord withdrawRecord = daoWithdrawRecordDao.getById(request.getId());
        if(ObjectUtil.isNull(withdrawRecord)){
            return Result.fail("未找到提现记录");
        }
        if(withdrawRecord.getStatus().intValue()!=0){
            return Result.fail("提现状态不正确");
        }
        DaoCustomerOpenAccount customerOpenAccount = customerOpenAccountDao.getById(withdrawRecord.getWalletId());
        llPayHelper.daoWithdrawVerifySmsCode(request.getOperatorId(),customerOpenAccount.getDaoUuid(),withdrawRecord,request.getSmsCode());
        return Result.success();
    }

    @ApiOperation(value = "提现列表", notes = "提现列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/withdrawPage", produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResult<DaoWithdrawRecordVO>  withdrawPage(@Valid @RequestBody DaoWithdrawPageRequest request) {
        Page<DaoWithdrawRecord> page = daoWithdrawRecordDao.getByWalletId(request.getWalletId(),request.getStartTime(),request.getEndTime(),request.getStatus(),request.toMp());
        Page<DaoWithdrawRecordVO> result = new Page<>(page.getCurrent(),page.getSize(),page.getTotal());
        List<DaoWithdrawRecordVO> vos = Lists.newArrayList();
        for (DaoWithdrawRecord record : page.getRecords()) {
            DaoWithdrawRecordVO daoWithdrawRecordVO = new DaoWithdrawRecordVO();
            daoWithdrawRecordVO.setCustomerOrderNo(record.getCustomerOrderNo());
            daoWithdrawRecordVO.setAmount(record.getAmount());
            daoWithdrawRecordVO.setRealAmount(record.getRealAmount());
            if(record.getStatus().intValue()==0){
                daoWithdrawRecordVO.setStatus("提现中");
            }
            if(record.getStatus().intValue()==1){
                daoWithdrawRecordVO.setStatus("成功");
            }
            if(record.getStatus().intValue()==2){
                daoWithdrawRecordVO.setStatus("失败");
            }
            daoWithdrawRecordVO.setRemark(record.getRemark());
            daoWithdrawRecordVO.setFeeAmount(record.getFeeAmount());
            daoWithdrawRecordVO.setCreateTime(record.getCreateTime());
            vos.add(daoWithdrawRecordVO);
        }
        result.setRecords(vos);
        return PageResult.success(result);
    }


    @ApiOperation(value = "绑定手机验证码申请", notes = "绑定手机验证码申请", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/regPhoneApply", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result regPhoneApply(@Valid @RequestBody RegPhoneRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getId());
        llPayHelper.regPhoneApply(request.getOperatorId(),userCreatorInfo.getDaoUuid(),request.getRegPhone());
        return Result.success();
    }



    @ApiOperation(value = "绑定手机验证码验证", notes = "绑定手机验证码验证", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/regPhoneVerify", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result regPhoneVerify(@Valid @RequestBody RegPhoneRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getId());
        llPayHelper.regPhoneVerify(request.getOperatorId(),userCreatorInfo.getDaoUuid(),request.getRegPhone(),request.getVerifyCode());
        return Result.success();
    }


    @ApiOperation(value = "获取支付验证码", notes = "获取支付验证码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getPaySms", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result getPaySms(@Valid @RequestBody IdRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getId());
        if(userCreatorInfo.getUserId()==null){
            return Result.fail("未设置主理人");
        }
        UserInfo userInfo = userInfoDao.getById(userCreatorInfo.getUserId());
        if(redisTemplate.hasKey(RedisKeyEnum.DAO_PAY_SMS.getKey()+userInfo.getUserTel())){
            return Result.fail(ErrorCode.SMS_ONE_MINUTE);
        }
        int code = RandomUtil.randomInt(100000, 999999);
        if(!smsCodeRecordService.sendTemplate(userInfo.getUserTel(),"2231922",new String[]{String.valueOf(code)})){
            return Result.fail(ErrorCode.SMS_FAIL);
        }
        redisTemplate.opsForValue().set(RedisKeyEnum.DAO_PAY_SMS.getKey()+userInfo.getUserTel(),"1",60L,TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(RedisKeyEnum.DAO_PAY_SMS_CODE.getKey()+userInfo.getUserTel(),String.valueOf(code),60L,TimeUnit.SECONDS);

        return Result.success();
    }


    @ApiOperation(value = "获取支付验证码", notes = "获取支付验证码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getPaySmsNew", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result getPaySmsNew(@Valid @RequestBody IdRequest request) {
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getId());
        if(StringUtils.isBlank(userCreatorInfo.getPhoneNo())){
            return Result.fail("未设置验证手机号");
        }
        if(redisTemplate.hasKey(RedisKeyEnum.DAO_PAY_SMS.getKey()+userCreatorInfo.getPhoneNo())){
            return Result.fail(ErrorCode.SMS_ONE_MINUTE);
        }
        int code = RandomUtil.randomInt(100000, 999999);
        if(!smsCodeRecordService.sendTemplate(userCreatorInfo.getPhoneNo(),"2231922",new String[]{String.valueOf(code)})){
            return Result.fail(ErrorCode.SMS_FAIL);
        }
        redisTemplate.opsForValue().set(RedisKeyEnum.DAO_PAY_SMS.getKey()+userCreatorInfo.getPhoneNo(),"1",60L,TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(RedisKeyEnum.DAO_PAY_SMS_CODE.getKey()+userCreatorInfo.getPhoneNo(),String.valueOf(code),60L,TimeUnit.SECONDS);

        return Result.success();
    }

    @ApiOperation(value = "大额行号查询", notes = "大额行号查询", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/largeLineNumberQuery", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<LargeLineNumberVO> largeLineNumberQuery(@Valid @RequestBody LargeLineNumberDTO largeLineNumberDTO) {
        JSONObject jsonObject = llPayHelper.largeLineNumberQuery(BeanUtil.copyProperties(largeLineNumberDTO, JSONObject.class));
        LargeLineNumberVO largeLineNumberVO = new LargeLineNumberVO();
        largeLineNumberVO.setBankCode(jsonObject.getString("bank_code"));
        String cardList = jsonObject.getString("card_list");
        List<LargeLineNumberListVO> largeLineNumberListVOS = JSONObject.parseArray(cardList, LargeLineNumberListVO.class);
        if (CollUtil.isNotEmpty(largeLineNumberListVOS)) {
            largeLineNumberVO.setCardList(largeLineNumberListVOS);
        }
        return Result.success(largeLineNumberVO);
    }

    @ApiOperation(value = "查询DAO钱包余额", notes = "查询DAO钱包余额", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getWalletInfo", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<DaoWalletSimpleVO> getWalletInfo(@Valid @RequestBody IdRequest request) {
        DaoWallet daoWallet = daoWalletService.getByDaoId(request.getId());
        return Result.success(daoWallet,DaoWalletSimpleVO.class);
    }

    @ApiOperation(value = "dao市值账号简单列表", notes = "dao市值账号简单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoMarketSimpleList", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<List<DaoFilterUserSimpleVO>> daoMarketSimpleList (@Valid @RequestBody IdRequest request) {
        return Result.successColl(filterIncomeListDao.getDaoFilterUser(request.getId(),null,new Page(1,999)).getRecords(),DaoFilterUserSimpleVO.class);
    }


    @ApiOperation(value = "dao市值账号列表", notes = "查询DAO钱包余额", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoMarketAccountList", produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResult<DaoFilterUserVO> daoMarketAccountList (@Valid @RequestBody DaoUserTelPageRequest request) {
        return PageResult.success(filterIncomeListDao.getDaoFilterUser(request.getDaoId(),request.getUserTel(),request.toMp()));
    }

    @ApiOperation(value = "查询钱包列表", notes = "查询钱包列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/walletPage", produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResult<DaoCustomerWalletVO> walletPage(@Valid @RequestBody DaoCustomerWalletChannelDTO walletChannelDTO) {
        Page<DaoCustomerOpenAccount> daoCustomerOpenAccountPage = customerOpenAccountService.getByDaoId(walletChannelDTO.getDaoId(), walletChannelDTO.getWalletChannel(),walletChannelDTO.toMp());
        Page<DaoCustomerWalletVO> page = new Page<>(daoCustomerOpenAccountPage.getCurrent(),daoCustomerOpenAccountPage.getSize(),daoCustomerOpenAccountPage.getTotal());
        List<DaoCustomerWalletVO> result = Lists.newArrayList();
        for (DaoCustomerOpenAccount record : daoCustomerOpenAccountPage.getRecords()) {
            DaoCustomerWalletVO daoCustomerWalletVO = new DaoCustomerWalletVO();
            daoCustomerWalletVO.setId(record.getId());
            daoCustomerWalletVO.setWalletChannel(record.getChannel());
            daoCustomerWalletVO.setBusinessName(record.getBusinessName());
            daoCustomerWalletVO.setFinishTime(record.getFinishTime());
            daoCustomerWalletVO.setRegPhone(DesensitizedUtil.mobilePhone(record.getRegPhone()));
            daoCustomerWalletVO.setBusinessLicenseCode(record.getBusinessLicenseCode());
            daoCustomerWalletVO.setBusinessLicenseImage(record.getBusinessLicenseImage());
            daoCustomerWalletVO.setStatus(record.getStatus());
            daoCustomerWalletVO.setRemark(record.getRemark());
            if(daoCustomerWalletVO.getStatus()== AccountStatusEnum.SUCCESS){
                daoCustomerWalletVO.setBalance(llPayHelper.getDaoBalance(walletChannelDTO.getOperatorId(),record.getDaoUuid()).getBigDecimal("amt_balaval").toPlainString());
            }else{
                daoCustomerWalletVO.setBalance("0.00");
            }
            daoCustomerWalletVO.setSumWithDrawAmount("0.00");
            result.add(daoCustomerWalletVO);
        }
        page.setRecords(result);
        return PageResult.success(page);
    }

    @ApiOperation(value = "B端开户", notes = "B端开户", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoOpenWallet", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result daoOpenWallet(@Valid @RequestBody DaoOpenWalletDTO dto) throws GlobalException {
        RLock lock = redisson.getLock(RedisKeyEnum.LL_BUSINESS_OPEN.getKey() + dto.getDaoId());
        try {
            boolean res = lock.tryLock(10,  TimeUnit.SECONDS);
            if (res) {
                customerOpenAccountService.customerOpenAccount(dto);
            }else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            throw new GlobalException("请勿重复操作");
        } finally {
            lock.unlock();
        }
        return Result.success();
    }


    @ApiOperation(value = "钱包银行卡列表", notes = "钱包银行卡列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/walletBankPage", produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResult<DaoAccountBankInfoVO> walletBankPage(@Valid @RequestBody DaoOperatorIdRequest request)  {
        Page<DaoAccountBankInfo> walletBankCardPage = customerOpenAccountService.getWalletBankCardPage(request.getId(), request.getDaoId(), request.toMp());
        Page<DaoAccountBankInfoVO> page = new Page<>(walletBankCardPage.getCurrent(),walletBankCardPage.getSize(),walletBankCardPage.getTotal());
        List<DaoAccountBankInfoVO> list = Lists.newArrayList();
        for (DaoAccountBankInfo record : walletBankCardPage.getRecords()) {
            DaoAccountBankInfoVO daoAccountBankInfoVO = new DaoAccountBankInfoVO();
            daoAccountBankInfoVO.setId(record.getId());
            daoAccountBankInfoVO.setDaoId(record.getDaoId());
            daoAccountBankInfoVO.setBankAccount(DesensitizedUtil.bankCard(record.getBankAccount()) );
            daoAccountBankInfoVO.setBankName(record.getBankName());
            daoAccountBankInfoVO.setProvince(record.getProvince());
            daoAccountBankInfoVO.setCity(record.getCity());
            daoAccountBankInfoVO.setPhone(DesensitizedUtil.mobilePhone(record.getPhone()));
            list.add(daoAccountBankInfoVO);
        }
        page.setRecords(list);
        return PageResult.success(page);
    }

    @ApiOperation(value = "B端开户验证", notes = "B端开户验证", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/daoOpenWalletVerify", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result daoOpenWalletVerify(@Valid @RequestBody VerifyOpenAccountDTO dto) {
        customerOpenAccountService.verifyOpenAccount(dto);
        return Result.success();
    }

    @ApiOperation(value = "开户信息查询", notes = "开户信息查询", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getAccountInfo", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<DaoOpenWalletDTO> daoOpenWalletVerify(@Valid @RequestBody DaoCustomerWalletRequest request) {
        return Result.success(customerOpenAccountService.getByIdAndDaoId(request.getId(),request.getDaoId()));
    }
    @ApiOperation(value = "转账第三方钱包", notes = "转账第三方钱包", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/transferToThird", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result transferToThird(@Valid @RequestBody DaoTransferRequest request) {
        if(StrUtil.isBlank(request.getVerifyCode())){
            return Result.fail(ErrorCode.VERIFICATION_ERROR);
        }
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        if(StringUtils.isBlank(userCreatorInfo.getPhoneNo())){
            return Result.fail("未设置验证手机号");
        }

        Object errorTime = redisTemplate.opsForValue().get(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo());
        if(errorTime!=null&&Integer.parseInt(String.valueOf(errorTime))>5){
            return Result.fail("尝试次数过多，请十分钟后再试");
        }
        Object code = redisTemplate.opsForValue().get(RedisKeyEnum.DAO_PAY_SMS_CODE.getKey() + userCreatorInfo.getPhoneNo());
        if(!StrUtil.equals(request.getVerifyCode(),String.valueOf(code))){
            redisTemplate.opsForValue().increment(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo());
            redisTemplate.expire(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo(),10L,TimeUnit.MINUTES);
            return Result.fail(ErrorCode.VERIFICATION_ERROR);
        }
        daoTransferService.daoApplyToThird(request.getId(),request.getDaoId(),request.getOperatorId(),request.getAmount());
        redisTemplate.delete(RedisKeyEnum.DAO_PAY_SMS.getKey()+userCreatorInfo.getPhoneNo());
        return Result.success();
    }

    @ApiOperation(value = "转账到市值账号", notes = "转账到市值账号", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/transferToMarket", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result transferToMarket(@Valid @RequestBody DaoTransferRequest request) {
        if(StrUtil.isBlank(request.getVerifyCode())){
            return Result.fail(ErrorCode.VERIFICATION_ERROR);
        }
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(request.getDaoId());
        if(StringUtils.isBlank(userCreatorInfo.getPhoneNo())){
            return Result.fail("未设置验证手机号");
        }
//        UserInfo userInfo = userInfoDao.getById(userCreatorInfo.getUserId());
        Object errorTime = redisTemplate.opsForValue().get(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo());
        if(errorTime!=null&&Integer.parseInt(String.valueOf(errorTime))>5){
            return Result.fail("尝试次数过多，请十分钟后再试");
        }
        Object code = redisTemplate.opsForValue().get(RedisKeyEnum.DAO_PAY_SMS_CODE.getKey() + userCreatorInfo.getPhoneNo());
        if(!StrUtil.equals(request.getVerifyCode(),String.valueOf(code))){
            redisTemplate.opsForValue().increment(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo());
            redisTemplate.expire(RedisKeyEnum.DAO_PAY_SMS_CODE_ERROR_TIME.getKey() + userCreatorInfo.getPhoneNo(),10L,TimeUnit.MINUTES);
            return Result.fail(ErrorCode.VERIFICATION_ERROR);
        }
        daoTransferService.daoApplyToMarket(request.getId(),request.getDaoId(),request.getOperatorId(),request.getAmount());
        redisTemplate.delete(RedisKeyEnum.DAO_PAY_SMS.getKey()+userCreatorInfo.getPhoneNo());

        return Result.success();
    }

    @ApiOperation(value = "市值转入", notes = "市值转入", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/marketTransferToDao", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result marketTransferToDao(@Valid @RequestBody DaoTransferRequest request) {
        daoTransferService.marketApplyToDao(request.getId(),request.getDaoId(),request.getOperatorId(),request.getAmount());
        return Result.success();
    }




    @ApiOperation(value = "资金流水", notes = "资金流水", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/transactionFlow", produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResult<WalletFlowDTO> transactionFlow(@Valid @RequestBody WalletFlowPageRequest request) {
        DaoCustomerOpenAccount daoCustomerOpenAccount = customerOpenAccountDao.getById(request.getId());
        if(ObjectUtil.isNull(daoCustomerOpenAccount)||daoCustomerOpenAccount.getDaoId().longValue()!=request.getDaoId().longValue()){
            return PageResult.fail("数据不存在");
        }
        if(daoCustomerOpenAccount.getStatus()!=AccountStatusEnum.SUCCESS){
            return PageResult.fail("开户未完成");
        }

        JSONObject result = llPayHelper.transactionFlow(request.getOperatorId(), daoCustomerOpenAccount.getDaoUuid(), request.getDcFlag(),request.getStartTime(), request.getEndTime(), request.toMp());
        Page page = new Page(result.getInteger("page_no"),request.getPageSize(),result.getInteger("total_num"));
        List<WalletFlowDTO> records = Lists.newArrayList();
        JSONArray acctbal_list = result.getJSONArray("acctbal_list");
        for (int i = 0; i < acctbal_list.size(); i++) {
            JSONObject jsonObject = acctbal_list.getJSONObject(i);
            WalletFlowDTO walletFlowDTO = new WalletFlowDTO();
            walletFlowDTO.setDealTime(DateUtil.parse(jsonObject.getString("txn_time"),"yyyyMMddHHmmss"));
            if(StrUtil.equals(jsonObject.getString("flag_dc"),"DEBIT")){
                walletFlowDTO.setDcFlag("出账");
            }else if(StrUtil.equals(jsonObject.getString("flag_dc"),"CREDIT")){
                walletFlowDTO.setDcFlag("入账");
            }
            walletFlowDTO.setAmount(jsonObject.getString("amt"));
            walletFlowDTO.setAfterBalance(jsonObject.getString("amt_bal"));
            walletFlowDTO.setOperatorType(txnType.get(jsonObject.getString("txn_type")));
            walletFlowDTO.setTradeNo(jsonObject.getString("jno_cli"));
            records.add(walletFlowDTO);
        }
        page.setRecords(records);

        return PageResult.success(page);
    }

    @ApiOperation(value = "解绑", notes = "解绑", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/unbind", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result  unbind(@Valid @RequestBody DaoUnbindDTO dto)  {
        customerOpenAccountService.unbind(dto);
        return Result.success();
    }

}


